-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--[[

    【建筑】【专属电器】【专属发电机】【锋锐的创造物】
    魔法1本解锁
    发电影响范围为半径32码（8个地皮），
        燃料值3000，以宝石为燃料（彩色除外），每个宝石恢复1000燃料。
        制造成本3红宝石，2蓝宝石，1电器元件，无法被破坏，拆卸用铲子，返还红、蓝宝石。
        集成探照灯功能，探照范围为半径32码，光圈大小为正方4格范围，颜色按照填入的宝石决定，
        此外，填入指定宝石有额外效果。（探照灯工作期间，每秒消耗0.1燃料）
        红宝石：让探照范围升温，效率按篝火最大火为准
        蓝宝石：让探照范围降温，效率按冰篝火最大火为准
        黄宝石：改为半径5格的范围照亮
        紫宝石：优先探照猪主人，其次再探照玩家，范围内玩家每分钟下降500san，猪人会发疯。
        绿宝石：范围内玩家每秒回复5生命、5san
        铥矿/铥矿碎片：范围内玩家每3次受到攻击就能触发一次铥矿皇冠的免伤效果。
        月石：让花变成草簇，杀死光圈范围内的影怪，让猪和狗变成月石雕塑

]]--
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 参数
    local MAX_BATTERY = 3000
    local MAX_BATTERY_EVOLUTION = 6000
    local BATTERY_AREA_RADIOUS = 32
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- 素材
    local assets = {

        Asset("ANIM", "anim/loramia_building_sharpstrike_creation.zip"),

    }
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
---
    local function snow_init(inst)
        if TheWorld.state.issnowcovered then
            -- inst.AnimState:Show("SNOW")
            inst.AnimState:ShowSymbol("snow")
        else
            -- inst.AnimState:Hide("SNOW")
            inst.AnimState:HideSymbol("snow")
        end    
    end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- workable install
    local function workable_install(inst)
        inst:ListenForEvent("Loramia_OnEntityReplicated.loramia_com_workable",function(inst,replica_com)
            replica_com:SetTestFn(function(inst,doer,right_click)
                if right_click and doer:HasTag("loramia") then
                    if doer.replica.loramia_com_talent_tree:IsUnlocked("evolution_sharpness") or TUNING.LORAMIA_DEBUGGING_MODE then
                        return true
                    end
                end                
            end)
            replica_com:SetText("loramia_building_sharpstrike_creation",STRINGS.ACTIONS.WRAPBUNDLE)
        end)
        if not TheWorld.ismastersim then
            return
        end
        inst:AddComponent("loramia_com_workable")
        inst.components.loramia_com_workable:SetOnWorkFn(function(inst,doer)
            local x,y,z = inst.Transform:GetWorldPosition()
            local record = inst:GetSaveRecord()
            local percent = inst.components.loramia_com_power_battery:GetPercent()
            local item = SpawnPrefab("loramia_building_sharpstrike_creation_kit")
            item.Transform:SetPosition(x,y,z)
            item.components.loramia_data:Set("record",record)
            item.components.finiteuses:SetPercent(percent)
            inst:Remove()
            return true
        end)
    end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- core_light
    local core_light_event = function(inst,flag)
        if flag == true and inst.core_light == nil then
            inst.core_light = SpawnPrefab("loramia_building_sharpstrike_creation_core_light")
            inst.core_light.entity:SetParent(inst.entity)
            inst.core_light.entity:AddFollower()
            inst.core_light.Follower:FollowSymbol(inst.GUID, "icon",0, 0, 0,true)
        end
        if flag == false and inst.core_light ~= nil then
            inst.core_light:Remove()
            inst.core_light = nil
        end
    end
    local function core_light_create(inst)
        if not TheWorld.ismastersim then
            return
        end
        inst:ListenForEvent("core_light",core_light_event)
    end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- acceptable install
    local gem_2_power = {
        ["redgem"] = 1000,
        ["orangegem"] = 1000,
        ["yellowgem"] = 1000,
        ["greengem"] = 1000,
        ["bluegem"] = 1000,
        ["purplegem"] = 1000,
    }
    local universal_energy_list = {
        ["nightmarefuel"] = 1000,
        ["nitre"] = 1000,
        ["charcoal"] = 1000,
        ["dreadstone"] = 3000,
    }
    local function GetTransMult(prefab,doer)
        ------------------------------------------
        -- 只有宝石才倍增
            if not gem_2_power[prefab] then
                return 1
            end
        ------------------------------------------
        --- 没天赋树不倍增
            local loramia_com_talent_tree = doer.replica.loramia_com_talent_tree
            if loramia_com_talent_tree == nil then
                return 1
            end
        ------------------------------------------
        --- 
            if loramia_com_talent_tree:IsUnlocked("sharper_IV") then
                return 3
            end
            if loramia_com_talent_tree:IsUnlocked("sharper_III") then
                return 2.5
            end
            if loramia_com_talent_tree:IsUnlocked("sharper_II") then
                return 2
            end
            if loramia_com_talent_tree:IsUnlocked("sharper_I") then
                return 1.5
            end
        ------------------------------------------
        return 1
    end
    local function GetStackNum(item)
        if item.components.stackable then
            return item.components.stackable:StackSize()
        else            
            return 1
        end
    end
    local function RemoveStackNum(item,num)
        num = num or 1
        if item.components.stackable then
            item.components.stackable:Get(num):Remove()
        else
            item:Remove()
        end
    end
    local function acceptable_install(inst)
        inst:ListenForEvent("Loramia_OnEntityReplicated.loramia_com_acceptable",function(inst,replica_com)
            replica_com:SetText("loramia_building_sharpstrike_creation",STRINGS.ACTIONS.ADDFUEL)
            replica_com:SetTestFn(function(inst,item,doer,right_click)
                if not right_click then
                    return false
                end
                if item and gem_2_power[item.prefab] then
                    return true
                end
                if doer and doer.replica.loramia_com_talent_tree
                    and (doer.replica.loramia_com_talent_tree:IsUnlocked("universal_energy") or TUNING.LORAMIA_DEBUGGING_MODE)
                    and universal_energy_list[item.prefab] then
                    return true
                end
                return false
            end)
        end)
        if not TheWorld.ismastersim then
            return
        end
        inst:AddComponent("loramia_com_acceptable")
        inst.components.loramia_com_acceptable:SetOnAcceptFn(function(inst,item,doer)
            ------------------------------------------------------------------------
            --- 处理天赋
                if doer and doer.replica.loramia_com_talent_tree and doer.replica.loramia_com_talent_tree:IsUnlocked("evolution_sharpness") then
                    inst.components.loramia_com_power_battery:SetMax(MAX_BATTERY_EVOLUTION)
                end
            ------------------------------------------------------------------------

            local value = gem_2_power[item.prefab] or universal_energy_list[item.prefab] or 1000
            local mult = GetTransMult(item.prefab,doer) or 1
            local value_per_one = value * mult

            local full_stack_value = value_per_one * GetStackNum(item)

            local max = inst.components.loramia_com_power_battery:GetMax()
            local current = inst.components.loramia_com_power_battery:GetCurrent()

            if current + full_stack_value >= max then
                inst.components.loramia_com_power_battery:SetCurrent(max)
                local value_cost = max - current
                local item_cost = math.ceil(value_cost / value_per_one)
                RemoveStackNum(item,item_cost)
            else
                inst.components.loramia_com_power_battery:DoDelta(full_stack_value)
                item:Remove()
            end
            return true
        end)
    end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- destory破坏返还
    local function destory_com_install(inst)
        inst:AddComponent("workable")
        inst.components.workable:SetWorkAction(ACTIONS.DIG)
        inst.components.workable:SetWorkLeft(1)
        inst.components.workable:SetOnWorkCallback(function(inst,worker)
            if worker and worker:HasTag("player") then
                ---
            else
                inst.components.workable:SetWorkLeft(1)
            end
        end)
        inst.components.workable:SetOnFinishCallback(function(inst,worker)
            if not (worker and worker:HasTag("player")) then
                return
            end
            local fx = SpawnPrefab("collapse_big")
            fx.Transform:SetPosition(inst.Transform:GetWorldPosition())
            inst.components.container:DropEverything()
            inst:AddComponent("lootdropper")
            for i = 1, 3, 1 do
                inst.components.lootdropper:SpawnLootPrefab("redgem")
            end
            for i = 1, 2, 1 do
                inst.components.lootdropper:SpawnLootPrefab("bluegem")
            end
            inst:Remove()
        end)
    end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- 建筑
    local function fn()
        local inst = CreateEntity()

        inst.entity:AddTransform()
        inst.entity:AddAnimState()
        inst.entity:AddSoundEmitter()
        inst.entity:AddMiniMapEntity()
        inst.entity:AddNetwork()

        inst.entity:AddDynamicShadow()
        -- inst.DynamicShadow:SetSize(1.3, 0.6)
        inst.DynamicShadow:SetSize(2, 1)

        inst.MiniMapEntity:SetIcon("loramia_building_sharpstrike_creation.tex")

        inst:SetPhysicsRadiusOverride(0.5)
        MakeObstaclePhysics(inst, inst.physicsradiusoverride)

        -- inst:SetDeploySmartRadius(DEPLOYSPACING_RADIUS[DEPLOYSPACING.PLACER_DEFAULT] / 2)

        inst:AddTag("structure")
        inst:AddTag("loramia_building_sharpstrike_creation")
        -----------------------------------------------------------------------------------------
        --- 动画
            inst.AnimState:SetBank("loramia_building_sharpstrike_creation")
            inst.AnimState:SetBuild("loramia_building_sharpstrike_creation")
            -- inst.AnimState:PlayAnimation("idle", true)
            inst.MiniMapEntity:SetIcon("loramia_building_sharpstrike_creation.tex")
        -----------------------------------------------------------------------------------------
        --- 
            inst.entity:SetPristine()
        -----------------------------------------------------------------------------------------
        ---- 容器和灯光安装
            local temp_fn = require("prefabs/06_buildings/01_sharpstrike_creation_container_and_light")
            if type(temp_fn) == "function" then
                temp_fn(inst)
            end
        -----------------------------------------------------------------------------------------
        ----
            workable_install(inst)
            core_light_create(inst)
            acceptable_install(inst)
        -----------------------------------------------------------------------------------------
        ----
            if not TheNet:IsDedicated() then
                inst:ListenForEvent("Loramia_OnEntityReplicated.loramia_com_power_battery",function(_,replica_com)
                    replica_com:SetTextColour(255/255,57/255,106/255)
                end)
            end
        -----------------------------------------------------------------------------------------
        if not TheWorld.ismastersim then
            return inst
        end
        -----------------------------------------------------------------------------------------
        --- 电池模块
            inst:AddComponent("loramia_com_power_battery")
            inst.components.loramia_com_power_battery:SetRadius(BATTERY_AREA_RADIOUS)
            inst.components.loramia_com_power_battery:SetMax(MAX_BATTERY)
            inst.components.loramia_com_power_battery:SetCurrent(MAX_BATTERY)
            inst.OnBuilt = function(inst,player) -- 从制作栏出来的时候检查天赋
                if player and player.replica.loramia_com_talent_tree and player.replica.loramia_com_talent_tree:IsUnlocked("evolution_sharpness") then
                    inst.components.loramia_com_power_battery:SetMax(MAX_BATTERY_EVOLUTION)
                    inst.components.loramia_com_power_battery:SetCurrent(MAX_BATTERY_EVOLUTION)
                end
            end
        -----------------------------------------------------------------------------------------
        --- 可检查
            inst:AddComponent("inspectable")
        -----------------------------------------------------------------------------------------
        ---- 积雪检查
            --[[ 
                【注意】 
                    官方的   MakeSnowCoveredPristine(inst)  MakeSnowCovered(inst) 
                    基本只对官方的东西有效，MOD作者需要自行在动画和代码上做额外处理。
                    方式有两种： 
                        基于文件夹的 隐藏/显示。
                        基于标记位的 隐藏显示。（这里示例用的就是这一种）
            ]]------
            -- local function snow_init(inst)
            --     if TheWorld.state.issnowcovered then
            --         -- inst.AnimState:Show("SNOW")
            --         inst.AnimState:ShowSymbol("snow")
            --     else
            --         -- inst.AnimState:Hide("SNOW")
            --         inst.AnimState:HideSymbol("snow")
            --     end    
            -- end
            inst:WatchWorldState("issnowcovered", snow_init)
            snow_init(inst)
        -----------------------------------------------------------------------------------------
        --- 动画控制器
            inst:DoTaskInTime(0,function()
                if not inst.components.loramia_com_power_battery:IsEmpty() then
                    inst.AnimState:PlayAnimation("place")
                    inst.AnimState:PushAnimation("idle", true)
                    inst:PushEvent("core_light",true)
                else
                    -- inst.AnimState:PlayAnimation("pre_empty")
                    -- inst.AnimState:PushAnimation("empty", false)
                    inst.AnimState:PlayAnimation("empty", false)
                    inst:PushEvent("core_light",false)
                end
            end)
            inst:ListenForEvent("value_update",function(_,_table)
                if _table and _table.on_empty then
                    inst.AnimState:PlayAnimation("pre_empty")
                    inst.AnimState:PushAnimation("empty", false)
                    inst:PushEvent("core_light",false)
                    return
                end
                if _table and _table.old == 0 and _table.new > 0 then
                    inst.AnimState:PlayAnimation("place")
                    inst.AnimState:PushAnimation("idle", true)
                    inst:PushEvent("core_light",true)
                    return
                end
            end)
        -----------------------------------------------------------------------------------------
        --- 拆解
            destory_com_install(inst)
        -----------------------------------------------------------------------------------------

        return inst
    end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- item
    local function item_fn()
        local inst = CreateEntity()

        inst.entity:AddTransform()
        inst.entity:AddAnimState()
        inst.entity:AddSoundEmitter()
        inst.entity:AddMiniMapEntity()
        inst.entity:AddNetwork()

        MakeInventoryPhysics(inst)
        MakeInventoryFloatable(inst, "med", 0.05, {0.85, 0.45, 0.85})

        inst.AnimState:SetBank("loramia_building_sharpstrike_creation")
        inst.AnimState:SetBuild("loramia_building_sharpstrike_creation")
        inst.AnimState:PlayAnimation("item")

        inst:AddTag("deploykititem")

        inst.entity:SetPristine()
        if not TheWorld.ismastersim then
            return inst
        end

        --------------------------------------------------------------------------
        ---
            inst:AddComponent("loramia_data")
        --------------------------------------------------------------------------
        ------ 物品名 和检查文本
            inst:AddComponent("inspectable")
            inst:AddComponent("inventoryitem")
            -- inst.components.inventoryitem:ChangeImageName("leafymeatburger")
            inst.components.inventoryitem.imagename = "loramia_building_sharpstrike_creation_kit"
            inst.components.inventoryitem.atlasname = "images/inventoryimages/loramia_building_sharpstrike_creation_kit.xml"
        -------------------------------------------------------------------
            MakeHauntableLaunch(inst)
        -------------------------------------------------------------------
        --- 落水影子
            local function shadow_init(inst)
                if inst:IsOnOcean(false) then       --- 如果在海里（不包括船）
                    -- inst.AnimState:Hide("SHADOW")
                    inst.AnimState:HideSymbol("shadow")
                else                                
                    -- inst.AnimState:Show("SHADOW")
                    inst.AnimState:ShowSymbol("shadow")
                end
            end
            inst:ListenForEvent("on_landed",shadow_init)
            shadow_init(inst)
        -------------------------------------------------------------------
        --- 积雪
            inst:WatchWorldState("issnowcovered", snow_init)
            snow_init(inst)
        -------------------------------------------------------------------
        --- 放置
            inst:AddComponent("deployable")
            inst.components.deployable.ondeploy = function(inst,pt,player)
                local record = inst.components.loramia_data:Get("record")
                local ret_inst = nil
                if record == nil then
                    ret_inst = SpawnPrefab("loramia_building_sharpstrike_creation")
                else
                    ret_inst = SpawnSaveRecord(record)
                end
                if player and player.replica.loramia_com_talent_tree and player.replica.loramia_com_talent_tree:IsUnlocked("evolution_sharpness") then
                    ret_inst.components.loramia_com_power_battery:SetMax(MAX_BATTERY_EVOLUTION)
                end
                ret_inst.Transform:SetPosition(pt.x,0,pt.z)
                inst:Remove()
            end
            inst.components.deployable:SetDeploySpacing(DEPLOYSPACING.NONE)
            inst.components.deployable.restrictedtag = "loramia"
        -------------------------------------------------------------------
        --- 耐久度
            inst:AddComponent("finiteuses")
            inst.components.finiteuses:SetMaxUses(MAX_BATTERY)
            inst.components.finiteuses:SetPercent(1)
            inst.components.finiteuses.Use = function() end
        -------------------------------------------------------------------
        --- 特效
            inst:DoTaskInTime(0,function()
                if inst.components.finiteuses:GetPercent() > 0 then
                    core_light_event(inst,true)
                else
                    core_light_event(inst,false)
                end
            end)
        -------------------------------------------------------------------
        return inst
    end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--- core light
    local function core_light_fn()
        local inst = CreateEntity()

        inst.entity:AddTransform()
        inst.entity:AddAnimState()    
        inst.entity:AddNetwork()

        inst.AnimState:SetBank("loramia_building_sharpstrike_creation")
        inst.AnimState:SetBuild("loramia_building_sharpstrike_creation")
        inst.AnimState:PlayAnimation("light",true)
        inst.AnimState:SetBloomEffectHandle("shaders/anim.ksh")

        inst:AddTag("CLASSIFIED")
        inst:AddTag("NOCLICK")
        inst:AddTag("INLIMBO")
        inst:AddTag("FX")
        inst:AddTag("NOCLICK")

        inst.entity:SetPristine()
        if not TheWorld.ismastersim then
            return inst
        end
        return inst
    end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-- placer
    local function placer_postinit_fn(inst)
        TheWorld:PushEvent("loramia_com_power_battery_indicator_active",inst)
        TheWorld:PushEvent("loramia_com_power_device_indicator_active",inst)
        snow_init(inst)

        local indicator = inst:SpawnChild("loramia_sfx_dotted_circle_client")
        indicator:PushEvent("Set",{
            radius = BATTERY_AREA_RADIOUS,
        })
        indicator.AnimState:SetAddColour(0, 1, 1, 0)
        indicator.AnimState:SetMultColour(0, 1, 1, 1)
        indicator.AnimState:SetBloomEffectHandle("shaders/anim.ksh")
    end
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


return Prefab("loramia_building_sharpstrike_creation", fn, assets),
    Prefab("loramia_building_sharpstrike_creation_core_light", core_light_fn, assets),
    Prefab("loramia_building_sharpstrike_creation_kit", item_fn, assets),
    MakePlacer("loramia_building_sharpstrike_creation_kit_placer", "loramia_building_sharpstrike_creation", "loramia_building_sharpstrike_creation", "empty", nil, nil, nil, nil, nil, nil, placer_postinit_fn)
